+2005-06-15 Kristian Rietveld <kris@gtk.org>
+
+ Patch for #163214 (reported by Tommi Komulainen) and fixes some
+ other scrolling/validation related bugs along the why.
+
+ * gtk/gtktreeview.c (gtk_tree_view_size_request): run
+ do_validate_rows once and don't queue a size request there,
+ (gtk_tree_view_size_allocate): don't update vadj value without
+ reason, sync top_row/dy after the window sizes and adjustments
+ are in sync again,
+ (validate_visible_area): always update dy when scrolling,
+ manually set top_row here after changing the vadj (don't depend
+ on _adjustment_changed and top_row/dy sync to do this), since we
+ now always set top_row here correctly, we can always free
+ scroll_to_path at the end which avoids infinite expose loops,
+ (do_validate_rows): add queue_resize boolean, remove top_row/dy
+ sync here, we cannot do it safely at this place since the
+ window sizes and adjustments are out of sync,
+ (validate_rows), (validate_rows_handler): update call to
+ do_validate_rows().
+
2005-06-14 Matthias Clasen <mclasen@redhat.com>
* gdk/x11/gdkcursor-x11.c (gdk_cursor_new_from_name): Add a
+2005-06-15 Kristian Rietveld <kris@gtk.org>
+
+ Patch for #163214 (reported by Tommi Komulainen) and fixes some
+ other scrolling/validation related bugs along the why.
+
+ * gtk/gtktreeview.c (gtk_tree_view_size_request): run
+ do_validate_rows once and don't queue a size request there,
+ (gtk_tree_view_size_allocate): don't update vadj value without
+ reason, sync top_row/dy after the window sizes and adjustments
+ are in sync again,
+ (validate_visible_area): always update dy when scrolling,
+ manually set top_row here after changing the vadj (don't depend
+ on _adjustment_changed and top_row/dy sync to do this), since we
+ now always set top_row here correctly, we can always free
+ scroll_to_path at the end which avoids infinite expose loops,
+ (do_validate_rows): add queue_resize boolean, remove top_row/dy
+ sync here, we cannot do it safely at this place since the
+ window sizes and adjustments are out of sync,
+ (validate_rows), (validate_rows_handler): update call to
+ do_validate_rows().
+
2005-06-14 Matthias Clasen <mclasen@redhat.com>
* gdk/x11/gdkcursor-x11.c (gdk_cursor_new_from_name): Add a
+2005-06-15 Kristian Rietveld <kris@gtk.org>
+
+ Patch for #163214 (reported by Tommi Komulainen) and fixes some
+ other scrolling/validation related bugs along the why.
+
+ * gtk/gtktreeview.c (gtk_tree_view_size_request): run
+ do_validate_rows once and don't queue a size request there,
+ (gtk_tree_view_size_allocate): don't update vadj value without
+ reason, sync top_row/dy after the window sizes and adjustments
+ are in sync again,
+ (validate_visible_area): always update dy when scrolling,
+ manually set top_row here after changing the vadj (don't depend
+ on _adjustment_changed and top_row/dy sync to do this), since we
+ now always set top_row here correctly, we can always free
+ scroll_to_path at the end which avoids infinite expose loops,
+ (do_validate_rows): add queue_resize boolean, remove top_row/dy
+ sync here, we cannot do it safely at this place since the
+ window sizes and adjustments are out of sync,
+ (validate_rows), (validate_rows_handler): update call to
+ do_validate_rows().
+
2005-06-14 Matthias Clasen <mclasen@redhat.com>
* gdk/x11/gdkcursor-x11.c (gdk_cursor_new_from_name): Add a
GtkTreePath *path);
static void validate_visible_area (GtkTreeView *tree_view);
static gboolean validate_rows_handler (GtkTreeView *tree_view);
+static gboolean do_validate_rows (GtkTreeView *tree_view,
+ gboolean size_request);
static gboolean validate_rows (GtkTreeView *tree_view);
static gboolean presize_handler_callback (gpointer data);
static void install_presize_handler (GtkTreeView *tree_view);
* sure we have some size. In practice, with a lot of static lists, this
* should get a good width.
*/
- validate_rows (tree_view);
+ do_validate_rows (tree_view, FALSE);
gtk_tree_view_size_request_columns (tree_view);
gtk_tree_view_update_size (GTK_TREE_VIEW (widget));
GList *tmp_list;
GtkTreeView *tree_view;
gboolean width_changed = FALSE;
- gboolean dy_changed = FALSE;
gint old_width = widget->allocation.width;
g_return_if_fail (GTK_IS_TREE_VIEW (widget));
tree_view->priv->vadjustment->lower = 0;
tree_view->priv->vadjustment->upper = MAX (tree_view->priv->vadjustment->page_size, tree_view->priv->height);
- if (tree_view->priv->vadjustment->value + allocation->height - TREE_VIEW_HEADER_HEIGHT (tree_view) > tree_view->priv->height)
- {
- double before = tree_view->priv->vadjustment->value;
- gtk_adjustment_set_value (tree_view->priv->vadjustment,
- MAX (tree_view->priv->height - tree_view->priv->vadjustment->page_size, 0));
- if (before != tree_view->priv->vadjustment->value)
- dy_changed = TRUE;
- }
-
gtk_adjustment_changed (tree_view->priv->vadjustment);
+
+ /* now the adjustments and window sizes are in sync, we can sync toprow/dy again */
+ if (gtk_tree_row_reference_valid (tree_view->priv->top_row))
+ gtk_tree_view_top_row_to_dy (tree_view);
+ else
+ gtk_tree_view_dy_to_top_row (tree_view);
if (GTK_WIDGET_REALIZED (widget))
{
else
gtk_widget_queue_draw (widget);
}
-
- if (dy_changed)
- gtk_widget_queue_draw (widget);
}
}
path = gtk_tree_row_reference_get_path (tree_view->priv->scroll_to_path);
if (path && !_gtk_tree_view_find_node (tree_view, path, &tree, &node))
{
+ /* we are going to scroll, and will update dy */
+ update_dy = TRUE;
+
gtk_tree_model_get_iter (tree_view->priv->model, &iter, path);
if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID) ||
GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_COLUMN_INVALID))
update_dy = TRUE;
}
+ /* if we scrolled to a path, we need to set the dy here,
+ * and sync the top row accordingly
+ */
+ if (tree_view->priv->scroll_to_path)
+ {
+ gint dy;
+
+ if (node != NULL)
+ dy = _gtk_rbtree_node_find_offset (tree, node) - area_above;
+ else
+ dy = 0;
+
+ gtk_adjustment_set_value (tree_view->priv->vadjustment, dy);
+
+ if (tree_view->priv->top_row)
+ {
+ gtk_tree_row_reference_free (tree_view->priv->top_row);
+ tree_view->priv->top_row = NULL;
+ }
+
+ tree_view->priv->top_row = gtk_tree_row_reference_new_proxy (G_OBJECT (tree_view), tree_view->priv->model, above_path);
+
+ need_redraw = TRUE;
+ }
+ else
+ gtk_tree_view_top_row_to_dy (tree_view);
+
+ /* update width/height and queue a resize */
if (size_changed)
{
GtkRequisition requisition;
/* We temporarily guess a size, under the assumption that it will be the
* same when we get our next size_allocate. If we don't do this, we'll be
* in an inconsistent state if we call top_row_to_dy. */
+
gtk_widget_size_request (GTK_WIDGET (tree_view), &requisition);
tree_view->priv->hadjustment->upper = MAX (tree_view->priv->hadjustment->upper, (gfloat)requisition.width);
tree_view->priv->vadjustment->upper = MAX (tree_view->priv->vadjustment->upper, (gfloat)requisition.height);
gtk_widget_queue_resize (GTK_WIDGET (tree_view));
}
- /* if we scroll at all, always update dy and kill the top_row */
- if (tree_view->priv->scroll_to_path &&
- ! GTK_RBNODE_FLAG_SET (tree_view->priv->tree->root, GTK_RBNODE_DESCENDANTS_INVALID))
- {
- update_dy = TRUE;
- if (tree_view->priv->top_row)
- {
- gtk_tree_row_reference_free (tree_view->priv->top_row);
- tree_view->priv->top_row = NULL;
- }
- }
-
- /* if we walk backwards at all, then we need to reset our dy. */
- if (update_dy)
- {
- gint dy;
- if (node != NULL)
- {
- dy = _gtk_rbtree_node_find_offset (tree, node) - area_above;
- }
- else
- {
- dy = 0;
- }
-
- gtk_adjustment_set_value (tree_view->priv->vadjustment, dy);
- need_redraw = TRUE;
- }
-
if (tree_view->priv->scroll_to_path)
{
gtk_tree_row_reference_free (tree_view->priv->scroll_to_path);
*/
static gboolean
-do_validate_rows (GtkTreeView *tree_view)
+do_validate_rows (GtkTreeView *tree_view, gboolean queue_resize)
{
GtkRBTree *tree = NULL;
GtkRBNode *node = NULL;
/* We temporarily guess a size, under the assumption that it will be the
* same when we get our next size_allocate. If we don't do this, we'll be
* in an inconsistent state when we call top_row_to_dy. */
+
gtk_widget_size_request (GTK_WIDGET (tree_view), &requisition);
tree_view->priv->hadjustment->upper = MAX (tree_view->priv->hadjustment->upper, (gfloat)requisition.width);
tree_view->priv->vadjustment->upper = MAX (tree_view->priv->vadjustment->upper, (gfloat)requisition.height);
gtk_adjustment_changed (tree_view->priv->hadjustment);
gtk_adjustment_changed (tree_view->priv->vadjustment);
- gtk_widget_queue_resize (GTK_WIDGET (tree_view));
- }
- if (gtk_tree_row_reference_valid (tree_view->priv->top_row))
- gtk_tree_view_top_row_to_dy (tree_view);
- else
- gtk_tree_view_dy_to_top_row (tree_view);
+ if (queue_resize)
+ gtk_widget_queue_resize (GTK_WIDGET (tree_view));
+ }
if (path) gtk_tree_path_free (path);
{
gboolean retval;
- retval = do_validate_rows (tree_view);
+ retval = do_validate_rows (tree_view, TRUE);
if (! retval && tree_view->priv->validate_rows_timer)
{
GDK_THREADS_ENTER ();
- retval = do_validate_rows (tree_view);
+ retval = do_validate_rows (tree_view, TRUE);
if (! retval && tree_view->priv->validate_rows_timer)
{
g_source_remove (tree_view->priv->validate_rows_timer);